package com.mytest.example.asyncservlet.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.mytest.example.asyncservlet.model.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Slf4j
@RequestMapping("/deferredResult")
@RestController
public class DeferredResultController {
    private Map<String, DeferredResult<ApiResult<Object>>> resultMap = new HashMap<>();

    @GetMapping("/request")
    public DeferredResult<ApiResult<Object>> request(@RequestParam("id") String id,
                                                     @RequestParam("timeout") String timeout) {
        log.info("线程ID={},Name={},请求进来了", Thread.currentThread().getId(), Thread.currentThread().getName());
        long timeoutMillis = TimeUnit.SECONDS.toMillis(10L);
        if (StrUtil.isNotEmpty(timeout)) {
            timeoutMillis = TimeUnit.SECONDS.toMillis(Convert.toLong(timeout));
        }
        log.info("超时时间 {} 毫秒", timeoutMillis);
        DeferredResult<ApiResult<Object>> deferredResult = new DeferredResult<>(timeoutMillis, ApiResult.fail("DeferredResult超时了"));
        deferredResult.onTimeout(() -> {
            log.info("线程ID={},Name={},调用超时了", Thread.currentThread().getId(), Thread.currentThread().getName());
        });
        deferredResult.onCompletion(() -> {
            log.info("线程ID={},Name={},调用完成了", Thread.currentThread().getId(), Thread.currentThread().getName());
        });
        resultMap.putIfAbsent(id, deferredResult);
        log.info("线程ID={},Name={},请求出去了", Thread.currentThread().getId(), Thread.currentThread().getName());
        return deferredResult;
    }

    @GetMapping("/setResult")
    public String setResult(@RequestParam("id") String id) {
        if (resultMap.containsKey(id)) {
            resultMap.get(id).setResult(ApiResult.success("DeferredResult调用成功"));
            resultMap.remove(id);
        }
        return "ok";
    }
}
